#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@desc: .

@Project ：kuberCloudTest
@File ：clusters.py
@Author ：admin
@Date ：2024/3/21 11:13 
"""
from kuberCloudTest.common.basic import basicUtils
from kuberCloudTest.common.constant import OFFSET, LIMIT, AsyncType
from kuberCloudTest.common.utils import _getOperationType, _getDetail
from kuberCloudTest.exception import KuberCloudException
from kuberCloudTest.urls import Urls


class clusterUtils(basicUtils):

    def __init__(self, accessToken):
        super().__init__(accessToken)


def get_utils(accessToken):
    return clusterUtils(accessToken=accessToken)


def getCluster(accessToken, clusterId=None, **kwargs):
    """
    获取集群
    :param clusterId: 集群 uuid
    :param accessToken: access token
    :param kwargs: limit:
                   offset:
                   keyword: xxx
    :return:
    """
    cluster_utils = get_utils(accessToken)
    content = cluster_utils.cloud_http_request.get(Urls.getCluster.value,
                                                   {
                                                       'offset': kwargs.get('offset', OFFSET),
                                                       'limit': kwargs.get('limit', LIMIT),
                                                       'keyword': kwargs.get('keyword', '')
                                                   })
    if clusterId:
        total = content.get('total', 0)
        content = get_utils(accessToken).cloud_http_request.get(
            Urls.getCluster.value, {'limit': total, 'offset': OFFSET})
        content = _getDetail(content, clusterId, 'clusterid')

    return content


def getClusterById(accessToken, clusterId):
    """
    通过集群ID查找集群
    :param accessToken:
    :param clusterId: 集群uuid
    :return:
    """
    return get_utils(accessToken).cloud_http_request.get(Urls.getClusterById.value, {'clusterid': clusterId})


def createCluster(accessToken,
                  clusterName, cloudCpuMode, architecture, cpuOverRatio, memoryOverRatio, memoryReserved, **kwargs):
    """
    创建集群
    :param accessToken:
    :param clusterName: 集群名称
    :param cloudCpuMode: CPU模式：
        选项：None、Haswell-noTSX、Haswell、Broadwell-noTSX、Broadwell、SandyBridge、IvyBridge、Conroe、Penryn、Nehalem、
             Westmere、Host-passthrough、Opteron_G1、Opteron_G2、Opteron_G3、Opteron_G4
        说明：
            1.默认选择None，集群内云主机的CPU模式由全局设置中的云主机CPU模式决定；
            2.若选择某一特定的CPU类型，集群内云主机将统一配置为该CPU类型；
            3.若选择host-passthrough，集群内云主机CPU的类型特性与物理机CPU的类型特性一致，但可能会导致从云主机内部和从云主机所在物理机查看云主机CPU使用率数值不一致。
    :param architecture: CPU架构：aarch64|x86_64|mips64el|loongarch64
    :param cpuOverRatio: CPU超分率取值范围：0.1~100
    :param memoryOverRatio: 内存超分率取值范围：0.1-100，0
    :param memoryReserved: 内存预留取值范围：0.1-1024Gb
    :param kwargs: remark: 备注
    :return:
    """
    operationType = 1601
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['clustername'] = clusterName
    data['cloudcpumode'] = cloudCpuMode
    data['architecture'] = architecture
    data['cpuoverratio'] = cpuOverRatio
    data['memoryoverratio'] = memoryOverRatio
    data['memoryreserved'] = memoryReserved
    data['remark'] = kwargs.get('remark', '')

    return get_utils(accessToken).cloud_http_request.post(Urls.createCluster.value, data=data)


def updateCluster(accessToken, clusterId,
                  clusterName, cloudCpuMode, architecture, cpuOverRatio, memoryOverRatio, memoryReserved, **kwargs):
    """
    更新集群
    :param accessToken:
    :param clusterId: 集群uuid
    :param clusterName: 集群名称
    :param cloudCpuMode: CPU模式：
        选项：None、Haswell-noTSX、Haswell、Broadwell-noTSX、Broadwell、SandyBridge、IvyBridge、Conroe、Penryn、Nehalem、
             Westmere、Host-passthrough、Opteron_G1、Opteron_G2、Opteron_G3、Opteron_G4
        说明：
            1.默认选择None，集群内云主机的CPU模式由全局设置中的云主机CPU模式决定；
            2.若选择某一特定的CPU类型，集群内云主机将统一配置为该CPU类型；
            3.若选择host-passthrough，集群内云主机CPU的类型特性与物理机CPU的类型特性一致，但可能会导致从云主机内部和从云主机所在物理机查看云主机CPU使用率数值不一致。
    :param architecture: CPU架构：aarch64|x86_64|mips64el|loongarch64
    :param cpuOverRatio: CPU超分率取值范围：0.1~100
    :param memoryOverRatio: 内存超分率取值范围：0.1-100，0
    :param memoryReserved: 内存预留取值范围：0.1-1024Gb
    :param kwargs: remark: 备注
    :return:
    """
    cluster = getCluster(accessToken=accessToken, clusterId=clusterId).get('obj', None)
    if not cluster:
        raise KuberCloudException('params error', 'diskSpec [{}] not exist'.format(clusterId))
    operationType = 1602
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['cloudcpumode'] = cloudCpuMode
    data['clustername'] = clusterName
    data['architecture'] = architecture
    data['cpuoverratio'] = cpuOverRatio
    data['memoryoverratio'] = memoryOverRatio
    data['memoryreserved'] = memoryReserved

    data['remark'] = kwargs.get('remark', cluster['remark'])
    return get_utils(accessToken).cloud_http_request.post(Urls.updateCluster.value, data=data)


def deleteCluster(accessToken, clusterIds):
    """
    删除集群
    :param accessToken:
    :param clusterIds: 集群uuid(多个使用英文逗号分割)
    :return:
    """
    operationType = 1603
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = clusterIds
    return get_utils(accessToken).cloud_http_request.post(Urls.deleteCluster.value, data=data)


def startCluster(accessToken, clusterIds):
    """
    启动集群
    :param accessToken:
    :param clusterIds: 集群uuid
    :return:
    """
    operationType = 1604
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['ids'] = clusterIds
    return get_utils(accessToken).cloud_http_request.post(Urls.startCluster.value, data=data)


def stopCluster(accessToken, clusterIds):
    """
    停止集群
    :param accessToken:
    :param clusterIds: 集群uuid
    :return:
    """
    operationType = 1605
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['ids'] = clusterIds
    return get_utils(accessToken).cloud_http_request.post(Urls.stopCluster.value, data=data)


def getMachineByCluster(accessToken, clusterId, **kwargs):
    """
    通过集群获取集群下的物理机
    :param accessToken:
    :param clusterId: 集群UUID
    :param kwargs: limit:
                   offset:
                   keyword: xxx
    :return:
    """
    return get_utils(accessToken).cloud_http_request.get(Urls.getMachineByCluster.value,
                                                         {
                                                             'clusterid': clusterId,
                                                             'offset': kwargs.get('offset', OFFSET),
                                                             'limit': kwargs.get('limit', LIMIT),
                                                             'keyword': kwargs.get('keyword', '')
                                                         })


def getL2NetworkByCluster(accessToken, clusterId, loaded: bool = False, **kwargs):
    """
    通过集群获取集群下的二层网络
    :param accessToken:
    :param clusterId: 集群UUID
    :param loaded: True时表示查询已加载的二层网络，False表示查询未加载的二层网络
    :param kwargs: limit:
                   offset:
                   keyword: xxx
    :return:
    """
    params = {
        'clusterid': clusterId,
        'offset': kwargs.get('offset', OFFSET),
        'limit': kwargs.get('limit', LIMIT),
        'keyword': kwargs.get('keyword', '')
    }
    if loaded:
        params['flag'] = 'loaded'
    return get_utils(accessToken).cloud_http_request.get(Urls.getL2NetworkByCluster.value, params=params)


def loadL2NetworkByCluster(accessToken, clusterId, networkId):
    """
    集群挂载二层网络
    :param accessToken:
    :param clusterId: 集群UUID
    :param networkId: 二层网络UUID
    :return:
    """
    operationType = 5104
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['clusterId'] = clusterId
    data['id'] = networkId
    return get_utils(accessToken).cloud_http_request.post(Urls.loadL2NetworkByCluster.value, data=data)


def unloadL2NetworkByCluster(accessToken, clusterId, networkId):
    """
    集群卸载二层网络
    :param accessToken:
    :param clusterId: 集群UUID
    :param networkId: 二层网络UUID
    :return:
    """
    operationType = 5105
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['clusterId'] = clusterId
    data['id'] = networkId
    return get_utils(accessToken).cloud_http_request.post(Urls.unloadL2NetworkByCluster.value, data=data)


def getStorageByCluster(accessToken, clusterId, loaded: bool = False, **kwargs):
    """
    通过集群获取集群下的存储
    :param accessToken:
    :param clusterId: 集群UUID
    :param loaded: True时表示查询已加载的主存储；False表示查询可加载的主存储
    :param kwargs: limit:
                   offset:
                   keyword: xxx
    :return:
    """
    params = {
        'clusterid': clusterId,
        'loaded': 1 if loaded else 0,
        'offset': kwargs.get('offset', OFFSET),
        'limit': kwargs.get('limit', LIMIT),
        'keyword': kwargs.get('keyword', '')
    }
    return get_utils(accessToken).cloud_http_request.get(Urls.getStorageByCluster.value, params=params)


def loadStorageByCluster(accessToken, clusterIds, storageId):
    """
    集群挂载存储
    :param accessToken:
    :param clusterIds: 集群UUID
    :param storageId: 存储UUID
    :return:
    """
    operationType = 1807
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['clusterIds'] = clusterIds
    data['primaryStorageId'] = storageId
    return get_utils(accessToken).cloud_http_request.post(Urls.loadStorageByCluster.value, data=data)


def unloadStorageByCluster(accessToken, clusterIds, storageId):
    """
    集群卸载载存储
    :param accessToken:
    :param clusterIds: 集群UUID
    :param storageId: 存储UUID
    :return:
    """
    operationType = 1808
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['clusterIds'] = clusterIds
    data['primaryStorageId'] = storageId
    return get_utils(accessToken).cloud_http_request.post(Urls.unloadStorageByCluster.value, data=data)
